package com.springcloud.controller;

import com.springcloud.biz.MessageBean;
import com.springcloud.topic.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 顾志杰
 * @date 2020/7/29-14:00
 */
@RestController
@Slf4j
public class Controller {

    private final MyTopic producer;

    private final GroupTopic groupTopic;

    private final DelayedTopic delayedTopic;

    private final ErrorTopic errorTopic;

    private final RequeueTopic requeueTopic;

    private final DlqTopic dlqTopic;

    private final FallbackTopic fallbackTopicProducer;

    @Autowired
    public Controller(MyTopic producer, GroupTopic groupTopic, DelayedTopic delayedTopic, ErrorTopic errorTopic, RequeueTopic requeueTopic, DlqTopic dlqTopic, FallbackTopic fallbackTopicProducer) {
        this.producer = producer;
        this.groupTopic = groupTopic;
        this.delayedTopic = delayedTopic;
        this.errorTopic = errorTopic;
        this.requeueTopic = requeueTopic;
        this.dlqTopic = dlqTopic;
        this.fallbackTopicProducer = fallbackTopicProducer;
    }

    @PostMapping("send")
    public void sendMessage(@RequestParam(value = "body") String body) {
        producer.output().send(MessageBuilder.withPayload(body).build());
    }

    /**
     * 分组发送
     *
     * @param body message
     */
    @PostMapping("sendGroup")
    public void sendMessageToGroup(@RequestParam(value = "body") String body) {
        groupTopic.output().send(MessageBuilder.withPayload(body).build());
    }

    /**
     * 延时发送
     *
     * @param body    messages
     * @param seconds 延时时间
     */
    @PostMapping("sendDM")
    public void sendDelayedMessage(@RequestParam(value = "body") String body,
                                   @RequestParam(value = "seconds") Integer seconds) {
        MessageBean messageBean = new MessageBean();
        messageBean.setPayload(body);
        log.info("ready to send delayed message");
        delayedTopic.output().send(MessageBuilder
                .withPayload(messageBean)
                .setHeader("x-delay", 1000 * seconds)
                .build());
    }

    /**
     * 异常单机重试
     *
     * @param body messages
     */
    @PostMapping("sendError")
    public void sendErrorMessage(@RequestParam(value = "body") String body) {
        MessageBean messageBean = new MessageBean();
        messageBean.setPayload(body);
        errorTopic.output().send(MessageBuilder.withPayload(messageBean).build());
    }


    /**
     * 异常联机重试（重新入列）
     *
     * @param body messages
     */
    @PostMapping("requeue")
    public void sendErrorMessageToRequeue(@RequestParam(value = "body") String body) {
        MessageBean messageBean = new MessageBean();
        messageBean.setPayload(body);
        requeueTopic.output().send(MessageBuilder.withPayload(messageBean).build());
    }


    /**
     * 死信队列
     *
     * @param body messages
     */
    @PostMapping("dlq")
    public void sendMessageToDlq(@RequestParam(value = "body") String body) {
        MessageBean messageBean = new MessageBean();
        messageBean.setPayload(body);
        dlqTopic.output().send(MessageBuilder.withPayload(messageBean).build());
    }

    /**
     * fallback + 升版
     *
     * @param body messages
     */
    @PostMapping("fallback")
    public void sendMessageToFallback(@RequestParam(value = "body") String body,
                                      @RequestParam(value = "version", defaultValue = "1.0") String version) {
        MessageBean messageBean = new MessageBean();
        messageBean.setPayload(body);
        fallbackTopicProducer
                .output()
                .send(
                        MessageBuilder.withPayload(messageBean)
                                .setHeader("version", version)
                                .build()
                );
    }
}
